<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Redux | Megasu的笔记</title>
    <meta name="generator" content="VuePress 1.5.4">
    <link rel="icon" href="/heima2020/favicon.ico">
    <meta name="description" content="Megasu的笔记整理">
    <meta name="author" content="Megasu">
    <meta name="Keywords" content="学习网站,前端,分享">
    <link rel="preload" href="/heima2020/assets/css/0.styles.aa663799.css" as="style"><link rel="preload" href="/heima2020/assets/js/app.e2adc9d2.js" as="script"><link rel="preload" href="/heima2020/assets/js/2.7389c9d3.js" as="script"><link rel="preload" href="/heima2020/assets/js/13.7524b74f.js" as="script"><link rel="prefetch" href="/heima2020/assets/js/10.8b750e5f.js"><link rel="prefetch" href="/heima2020/assets/js/11.9224f975.js"><link rel="prefetch" href="/heima2020/assets/js/12.3ea117b6.js"><link rel="prefetch" href="/heima2020/assets/js/14.cee0fcf8.js"><link rel="prefetch" href="/heima2020/assets/js/15.7a4a27f7.js"><link rel="prefetch" href="/heima2020/assets/js/16.947d882b.js"><link rel="prefetch" href="/heima2020/assets/js/17.79d3becb.js"><link rel="prefetch" href="/heima2020/assets/js/18.48208e3a.js"><link rel="prefetch" href="/heima2020/assets/js/19.3d0c49ef.js"><link rel="prefetch" href="/heima2020/assets/js/20.1f6114c8.js"><link rel="prefetch" href="/heima2020/assets/js/21.85e67b4a.js"><link rel="prefetch" href="/heima2020/assets/js/22.ce482f4d.js"><link rel="prefetch" href="/heima2020/assets/js/23.a150bd35.js"><link rel="prefetch" href="/heima2020/assets/js/24.8cd80d5d.js"><link rel="prefetch" href="/heima2020/assets/js/25.0001c7c1.js"><link rel="prefetch" href="/heima2020/assets/js/26.aa4d65a5.js"><link rel="prefetch" href="/heima2020/assets/js/27.baffff1d.js"><link rel="prefetch" href="/heima2020/assets/js/28.20430dcf.js"><link rel="prefetch" href="/heima2020/assets/js/29.7bbc3c04.js"><link rel="prefetch" href="/heima2020/assets/js/3.0076a912.js"><link rel="prefetch" href="/heima2020/assets/js/30.5f74696f.js"><link rel="prefetch" href="/heima2020/assets/js/31.a0bf56d6.js"><link rel="prefetch" href="/heima2020/assets/js/32.dd5a93dd.js"><link rel="prefetch" href="/heima2020/assets/js/33.92de7335.js"><link rel="prefetch" href="/heima2020/assets/js/34.bf468ed6.js"><link rel="prefetch" href="/heima2020/assets/js/35.28502be1.js"><link rel="prefetch" href="/heima2020/assets/js/36.3622a14c.js"><link rel="prefetch" href="/heima2020/assets/js/37.626e17d3.js"><link rel="prefetch" href="/heima2020/assets/js/38.860020b8.js"><link rel="prefetch" href="/heima2020/assets/js/39.c092c283.js"><link rel="prefetch" href="/heima2020/assets/js/4.586af112.js"><link rel="prefetch" href="/heima2020/assets/js/40.a6ba2743.js"><link rel="prefetch" href="/heima2020/assets/js/41.43d70bcd.js"><link rel="prefetch" href="/heima2020/assets/js/42.6486a709.js"><link rel="prefetch" href="/heima2020/assets/js/43.670b256a.js"><link rel="prefetch" href="/heima2020/assets/js/44.eb371480.js"><link rel="prefetch" href="/heima2020/assets/js/45.5b45f11e.js"><link rel="prefetch" href="/heima2020/assets/js/46.bc59be94.js"><link rel="prefetch" href="/heima2020/assets/js/47.ec36fca9.js"><link rel="prefetch" href="/heima2020/assets/js/48.51e80f8f.js"><link rel="prefetch" href="/heima2020/assets/js/5.6eb7e243.js"><link rel="prefetch" href="/heima2020/assets/js/6.1b7d5a6d.js"><link rel="prefetch" href="/heima2020/assets/js/7.f611fe3c.js"><link rel="prefetch" href="/heima2020/assets/js/8.c14cc922.js"><link rel="prefetch" href="/heima2020/assets/js/9.cd5538bb.js">
    <link rel="stylesheet" href="/heima2020/assets/css/0.styles.aa663799.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/heima2020/" class="home-link router-link-active"><!----> <span class="site-name">Megasu的笔记</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/heima2020/" class="nav-link">
  首页
</a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/heima2020/" class="nav-link">
  首页
</a></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><a href="/heima2020/node/day01" class="sidebar-heading clickable open"><span>Node</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/heima2020/node/day01.html" class="sidebar-link">Node 第 1 天</a></li><li><a href="/heima2020/node/day02.html" class="sidebar-link">Node 第 2 天</a></li><li><a href="/heima2020/node/day03.html" class="sidebar-link">Node 第 3 天</a></li><li><a href="/heima2020/node/day04.html" class="sidebar-link">Node 第 4 天</a></li><li><a href="/heima2020/node/day05.html" class="sidebar-link">Node 第 5 天</a></li><li><a href="/heima2020/node/day06.html" class="sidebar-link">Node 第 6 天</a></li><li><a href="/heima2020/node/day07.html" class="sidebar-link">Node 第 7 天</a></li><li><a href="/heima2020/node/day08.html" class="sidebar-link">Node 第 8 天</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h2 id="redux"><a href="#redux" class="header-anchor">#</a> Redux</h2> <p><a href="https://www.redux.org.cn/" target="_blank" rel="noopener noreferrer">中文文档<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <p><a href="https://redux.js.org/" target="_blank" rel="noopener noreferrer">英文文档<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <blockquote><p>Redux =  Reducer + Flux</p></blockquote> <p>Redux  是 React中的状态管理容器，可以理解为存放 公用数据的地方，提供一种更加规范和安全的方式去定义组件之间的公用数据（想象一下兄弟组件传值的过程）。对于初学者来说，它的使用并不简单。</p> <p><img src="/heima2020/assets/img/1560256957243.27df4fe4.png" alt="1560256957243"></p> <h3 id="redux概念"><a href="#redux概念" class="header-anchor">#</a> redux概念</h3> <h4 id="action"><a href="#action" class="header-anchor">#</a> Action</h4> <blockquote><p>行为</p></blockquote> <p><code>Action</code> 是把数据从应用。传到 <code>store</code> 的有效载荷。我们的数据只能通过 <code>Action</code>来触发，修改。</p> <h4 id="reducer"><a href="#reducer" class="header-anchor">#</a> Reducer</h4> <p><code>Reducers</code> 负责接收 <code>action</code>，然后根据<code>action</code>去处理<code>store</code></p> <p>不能直接修改原来的<code>state</code>。</p> <h4 id="store"><a href="#store" class="header-anchor">#</a> Store</h4> <p><code>store</code>其实是一个仓库，<code>redux</code>应用只有一个<code>store</code>，当需要拆分数据时，不能拆分<code>store</code>，但可以拆分<code>reducer</code></p> <h3 id="工作流"><a href="#工作流" class="header-anchor">#</a> 工作流</h3> <p><img src="/heima2020/assets/img/redux-flow.9ba0310b.png" alt="img"></p> <h3 id="如何学习"><a href="#如何学习" class="header-anchor">#</a> 如何学习</h3> <p>我们将会通过两种方式来学习redux</p> <ol><li>一是 原生redux的基本使用 （redux 是脱离了react存在的一个单独的库，可以融入到各大框架，原生js的，vue，react）</li> <li>二是 企业级 react-redux的使用</li> <li>以上两个的设计思路 都是一样的,只不过 <code>react-redux</code> 基于 react 和 redux 做了一些封装,使redux的使用更加贴近 react的语法而已。</li></ol> <h3 id="要点"><a href="#要点" class="header-anchor">#</a> 要点</h3> <p>应用中所有的 state 都以一个对象树的形式储存在一个单一的 <em>store</em> 中。</p> <p>惟一改变 state 的办法是触发 <em>action</em>，一个描述发生什么的对象。</p> <p>为了描述 action 如何改变 state 树，你需要编写 <em>reducers</em>。</p> <p>就是这样！</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> createStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux'</span><span class="token punctuation">;</span>

<span class="token comment">/**
 * 这是一个 reducer，形式为 (state, action) =&gt; state 的纯函数。
 * 描述了 action 如何把 state 转变成下一个 state。
 *
 * state 的形式取决于你，可以是基本类型、数组、对象、
 * 甚至是 Immutable.js 生成的数据结构。惟一的要点是
 * 当 state 变化时需要返回全新的对象，而不是修改传入的参数。
 *
 * 下面例子使用 `switch` 语句和字符串来做判断，但你可以写帮助类(helper)
 * 根据不同的约定（如方法映射）来判断，只要适用你的项目即可。
 */</span>
<span class="token keyword">const</span> <span class="token function-variable function">counter</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">switch</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">case</span> <span class="token string">'ADD'</span><span class="token operator">:</span>
    <span class="token keyword">return</span> state <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token keyword">case</span> <span class="token string">'LESS'</span><span class="token operator">:</span>
    <span class="token keyword">return</span> state <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token keyword">default</span><span class="token operator">:</span>
    <span class="token keyword">return</span> state<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// 创建 Redux store 来存放应用的状态。</span>
<span class="token comment">// API 是 { subscribe, dispatch, getState }。</span>
<span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">createStore</span><span class="token punctuation">(</span>counter<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 可以手动订阅更新，也可以事件绑定到视图层。</span>
store<span class="token punctuation">.</span><span class="token function">subscribe</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'store 仓库的数据'</span><span class="token punctuation">,</span> store<span class="token punctuation">.</span><span class="token function">getState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 改变内部 state 惟一方法是 dispatch 一个 action。</span>
<span class="token comment">// action 可以被序列化，用日记记录和储存下来，后期还可以以回放的方式执行</span>
store<span class="token punctuation">.</span><span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> type<span class="token operator">:</span> <span class="token string">'ADD'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 1</span>
store<span class="token punctuation">.</span><span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> type<span class="token operator">:</span> <span class="token string">'ADD'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 2</span>
store<span class="token punctuation">.</span><span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span> type<span class="token operator">:</span> <span class="token string">'LESS'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 1</span>
</code></pre></div><p>你应该把要做的修改变成一个普通对象，这个对象被叫做 <em>action</em>，而不是直接修改 state。</p> <p>然后编写专门的函数来决定每个 action 如何改变应用的 state，这个函数被叫做 <em>reducer</em>。</p> <p>Redux 不支持多个 store，只有一个单一的 store 和一个根级的 reduce 函数（reducer）。</p> <p>随着应用不断变大，你应该把根级的 reducer 拆成多个小的 reducers，分别独立地操作 state 树的不同部分，而不是添加新的 stores。这就像一个 React 应用只有一个根级的组件，这个根组件又由很多小组件构成。（高级用法）</p> <h3 id="原生的-redux"><a href="#原生的-redux" class="header-anchor">#</a> 原生的 redux</h3> <ol><li><p>安装依赖</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code>yarn add redux
</code></pre></div></li> <li><p>新建管理员 <code>store/reducer/index.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 1 定义默认数据，后期可以从接口中获取</span>
<span class="token keyword">const</span> defaultState <span class="token operator">=</span> <span class="token punctuation">{</span>
  num<span class="token operator">:</span> <span class="token operator">-</span><span class="token number">1</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 2 创建和对外暴露一个函数 返回state</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> defaultState</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> state<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>新建仓库 <code>store/index.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 1 引入 store生成器</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> createStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;redux&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 2 引入reducer</span>
<span class="token keyword">import</span> reducer <span class="token keyword">from</span> <span class="token string">&quot;./reducer&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 3 创建和对外暴露store</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">createStore</span><span class="token punctuation">(</span>reducer<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div></li> <li><p>组件引入仓库</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> store <span class="token keyword">from</span> <span class="token string">&quot;./store&quot;</span><span class="token punctuation">;</span>
</code></pre></div></li> <li><p>组件使用仓库中的全局数据</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token operator">=</span><span class="token punctuation">{</span>
        <span class="token operator">...</span>store<span class="token punctuation">.</span><span class="token function">getState</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>修改仓库中的数据</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token function-variable function">handleClick</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
    store<span class="token punctuation">.</span><span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token punctuation">{</span>type<span class="token operator">:</span><span class="token string">&quot;ADD&quot;</span><span class="token punctuation">,</span>value<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>修改管理员 <code>./store/reducer/index.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> defaultState<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span> action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token string">&quot;ADD&quot;</span> <span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">const</span> newState <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        newState<span class="token punctuation">.</span>num <span class="token operator">+=</span> action<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
        <span class="token keyword">return</span> newState<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token keyword">return</span> state<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>此时 组件中的数据想要看到最新的值 需要修改代码 (使用订阅模式)</p> <div class="language-js extra-class"><pre class="language-js"><code>  <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    store<span class="token punctuation">.</span><span class="token function">subscribe</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    	<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> num<span class="token operator">:</span> store<span class="token punctuation">.</span><span class="token function">getState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>num <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  	<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
</code></pre></div></li> <li><p>当该组件被销毁的时候,需要取消订阅</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code>  Unsubscribe <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
  <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>UnsubscribeFn <span class="token operator">=</span> store<span class="token punctuation">.</span><span class="token function">subscribe</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    	<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> num<span class="token operator">:</span> store<span class="token punctuation">.</span><span class="token function">getState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>num <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  	<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">UnsubscribeFn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
</code></pre></div></li></ol> <h2 id="react-redux"><a href="#react-redux" class="header-anchor">#</a> react-redux</h2> <h3 id="关键步骤"><a href="#关键步骤" class="header-anchor">#</a> 关键步骤</h3> <ol><li>安装依赖</li> <li>创建<code>store</code></li> <li>创建<code>reducer</code></li> <li>将<code>store</code>数据映射到组件中</li> <li>组件触发事件 创建<code>action</code></li> <li>将<code>action</code>派发到<code>store</code></li> <li><code>store</code>自己调用reducer</li></ol> <h3 id="实现目标"><a href="#实现目标" class="header-anchor">#</a> 实现目标</h3> <p><img src="/heima2020/assets/img/2019-04-30090218.bc3e6e17.gif" alt="2019-04-30090218"></p> <ol><li>可以发请求加载数据</li> <li>点击 <code>+</code> <code>-</code> 组件 会修改数据</li></ol> <h3 id="安装依赖"><a href="#安装依赖" class="header-anchor">#</a> 安装依赖</h3> <blockquote><p>redux 是核心库 react-redux是负责将react组件连接redux</p></blockquote> <div class="language-sh extra-class"><pre class="language-sh"><code><span class="token function">yarn</span> <span class="token function">add</span> redux react-redux --dev
</code></pre></div><h3 id="新建redux配套文件"><a href="#新建redux配套文件" class="header-anchor">#</a> 新建redux配套文件</h3> <p>在<code>src/store/</code>目录下新建 以下文件</p> <ol><li><code>index.js</code>   store核心文件</li> <li><code>reducer/index.js</code>  负责记录操作的<code>reducer</code>文件</li></ol> <p><code>reducer.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 1 定义默认数据，后期可以从接口中获取</span>
<span class="token keyword">const</span> defaultState <span class="token operator">=</span> <span class="token punctuation">{</span>
  num<span class="token operator">:</span> <span class="token operator">-</span><span class="token number">1</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 2 创建和对外暴露一个函数 返回state</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> defaultState<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> state<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><code>store/index.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 1 引入 store生成器</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> createStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;redux&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 2 引入reducer</span>
<span class="token keyword">import</span> reducer <span class="token keyword">from</span> <span class="token string">&quot;./reducer&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 3 创建和对外暴露store</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">createStore</span><span class="token punctuation">(</span>reducer<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><code>src/index.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">'react-dom'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token string">'./index.css'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">'./App'</span><span class="token punctuation">;</span>
<span class="token comment">// 1 引入 react-redux  负责将store和组件连接起来</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> Provider <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;react-redux&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 1 引入 store</span>
<span class="token keyword">import</span> store <span class="token keyword">from</span> <span class="token string">&quot;./store&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// 2 将App用 Provider 标签包裹起来</span>
<span class="token comment">// 2 将store通过属性的方式传递到App组件上</span>
ReactDOM<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Provider</span></span> <span class="token attr-name">store</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>store<span class="token punctuation">}</span></span> <span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">App</span></span> <span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Provider</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">,</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'root'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><code>App.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Component <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token comment">// 1 引入 react-redux 中 链接 组件和store的对象 connect</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> connect <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;react-redux&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token comment">// 4 使用store中的数据 </span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>num<span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>hr</span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"> + </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"> - </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// 2 将 store中的数据传递到 App的props上</span>
<span class="token keyword">const</span> <span class="token function-variable function">mapStateToProps</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    num<span class="token operator">:</span> state<span class="token punctuation">.</span>num
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>


<span class="token comment">// 3 用 connect 将store中的数据通过props的方式传递到App上</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">connect</span><span class="token punctuation">(</span>mapStateToProps<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span>

</code></pre></div><h4 id="思考"><a href="#思考" class="header-anchor">#</a> 思考</h4> <p>以上代码，“action去了哪里了呢？ ”</p> <p>答：没有操作数据的行为，当然么有<code>action</code>了</p> <h3 id="抽离组件-绑定事件"><a href="#抽离组件-绑定事件" class="header-anchor">#</a> 抽离组件，绑定事件</h3> <p>编辑<code>App.js</code></p> <p>将 两个按钮 抽离出来变成两个组件，这才满足组件共享数据的设计理念</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 加</span>
<span class="token keyword">class</span> <span class="token class-name">AddBtn</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>numAdd<span class="token punctuation">}</span></span> <span class="token punctuation">&gt;</span></span><span class="token plain-text">+</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
 
<span class="token comment">// 减</span>
<span class="token keyword">class</span> <span class="token class-name">SubstraBtn</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>numSubStra<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">-</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>num<span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>hr</span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">/* 使用组件 传递props */</span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AddBtn</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">this</span><span class="token punctuation">.</span><span class="token attr-value">props</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AddBtn</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">/* 使用组件 传递props*/</span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">SubstraBtn</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">this</span><span class="token punctuation">.</span><span class="token attr-value">props</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">SubstraBtn</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>此时，我们发现 两个组件上都绑定了点击事件</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>numAdd<span class="token punctuation">}</span></span> <span class="token punctuation">&gt;</span></span><span class="token plain-text">+</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>numSubStra<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">-</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>所以，现在我们需要另外定义 两个事件，在redux中就叫做行为 <code>action</code></p> <p>和  <code>mapStateToProps</code>同层级，创建 行为合集  <code>mapDispatchToProps</code>，并且把它传入 <code>connect</code>的第二个参数内。</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 2 将行为action 链接到store和组件上</span>
<span class="token keyword">const</span> <span class="token function-variable function">mapDispatchToProps</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">dispatch</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    <span class="token comment">// 点击事件中的加</span>
    <span class="token function-variable function">numAdd</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// 创建一个action，负责将行为类型和数据交给reducer</span>
      <span class="token keyword">const</span> action <span class="token operator">=</span> <span class="token punctuation">{</span>
        <span class="token comment">// type是一个自定义的字符串</span>
        type<span class="token operator">:</span> <span class="token string">&quot;NUM_ADD&quot;</span><span class="token punctuation">,</span>
        value<span class="token operator">:</span> <span class="token number">1</span>
      <span class="token punctuation">}</span><span class="token punctuation">;</span>
      <span class="token comment">// 派发行为- 会将action 派发到  reducer中</span>
      <span class="token function">dispatch</span><span class="token punctuation">(</span>action<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token comment">// 点击事件中的减</span>
    <span class="token function-variable function">numSubStra</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> action <span class="token operator">=</span> <span class="token punctuation">{</span>
        type<span class="token operator">:</span> <span class="token string">&quot;NUM_SUBSTRA&quot;</span><span class="token punctuation">,</span>
        value<span class="token operator">:</span> <span class="token number">1</span>
      <span class="token punctuation">}</span><span class="token punctuation">;</span>
      <span class="token function">dispatch</span><span class="token punctuation">(</span>action<span class="token punctuation">)</span><span class="token punctuation">;</span>
     <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// 3 用 connect 将store中的数据通过props的方式传递到App上</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">connect</span><span class="token punctuation">(</span>mapStateToProps<span class="token punctuation">,</span> mapDispatchToProps<span class="token punctuation">)</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span>
</code></pre></div><h3 id="编辑-reducer-逻辑"><a href="#编辑-reducer-逻辑" class="header-anchor">#</a> 编辑 reducer 逻辑</h3> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 1 定义默认数据，后期可以从接口中获取</span>
<span class="token keyword">const</span> defaultState <span class="token operator">=</span> <span class="token punctuation">{</span>
  num<span class="token operator">:</span> <span class="token operator">-</span><span class="token number">1</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 2 创建和对外暴露一个函数 返回state</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> defaultState<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 当 action被派发时(dispatch)，会触发</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token string">&quot;NUM_ADD&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 复制一份旧的state</span>
    <span class="token keyword">let</span> newState <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>
    newState<span class="token punctuation">.</span>num <span class="token operator">+=</span> action<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
    <span class="token comment">// 将新的state返回，即可触发store的更新</span>
    <span class="token keyword">return</span> newState<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token string">&quot;NUM_SUBSTRA&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 复制一份旧的state</span>
    <span class="token keyword">let</span> newState <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>
    newState<span class="token punctuation">.</span>num <span class="token operator">-=</span> action<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
    <span class="token keyword">return</span> newState<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token keyword">return</span> state<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="优化手段"><a href="#优化手段" class="header-anchor">#</a> 优化手段</h3> <p>通过以上步骤，可以把redux的使用流程走完，但是在公司中，还会对以上的代码进行优化，存在以下优化的步骤</p> <ol><li>将state中的数据修改为对象形式，因为数据一般不会这么简单。</li> <li>将action的type类型提取成常量的形式，避免手写字符串出错</li> <li>将action的创建由字面量改为 action生成器来创建，方便后期代码的维护和测试</li> <li>拆分和合并reducer，有时候，会根据不同的数据使用不同的reducer</li> <li>添加异步action，因为有时候我们的数据是从异步中获取的不是同步的方式。</li></ol> <h4 id="将state中的数据修改为对象形式"><a href="#将state中的数据修改为对象形式" class="header-anchor">#</a> 将state中的数据修改为对象形式</h4> <p><strong>编辑 reducer/index.js</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">const</span> defaultState <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">// 修改为对象形式</span>
  payload<span class="token operator">:</span> <span class="token punctuation">{</span>
    num<span class="token operator">:</span> <span class="token operator">-</span><span class="token number">1</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> defaultState<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token string">&quot;NUM_ADD&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> newState <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 修改为对象形式</span>
    newState<span class="token punctuation">.</span>payload<span class="token punctuation">.</span>num <span class="token operator">+=</span> action<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
    <span class="token keyword">return</span> newState<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token string">&quot;NUM_SUBSTRA&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> newState <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 修改为对象形式</span>
    newState<span class="token punctuation">.</span>payload<span class="token punctuation">.</span>num <span class="token operator">-=</span> action<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
    <span class="token keyword">return</span> newState<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token keyword">return</span> state<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>修改App.js中使用的state的代码</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">const</span> <span class="token function-variable function">mapStateToProps</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
     <span class="token punctuation">{</span><span class="token comment">/* 修改为对象的形式 */</span><span class="token punctuation">}</span>
    num<span class="token operator">:</span> state<span class="token punctuation">.</span>payload<span class="token punctuation">.</span>num
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="将action的type类型提取成常量的形式"><a href="#将action的type类型提取成常量的形式" class="header-anchor">#</a> 将action的type类型提取成常量的形式</h4> <p>新建文件 <code>src/store/actionType/index.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token constant">NUM_ADD</span> <span class="token operator">=</span> <span class="token string">&quot;NUM_ADD&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token constant">NUM_SUBSTRA</span> <span class="token operator">=</span> <span class="token string">&quot;NUM_SUBSTRA&quot;</span><span class="token punctuation">;</span>
</code></pre></div><p>修改 使用到了 <code>NUM_ADD</code>的文件</p> <p>编辑 <code>src/store/reducer/index.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 1 导入 type常量</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token constant">NUM_ADD</span><span class="token punctuation">,</span> <span class="token constant">NUM_SUBSTRA</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;../actionType&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> defaultState<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 2 修改为常量的方式</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token constant">NUM_ADD</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token operator">...</span><span class="token operator">...</span>
  <span class="token punctuation">}</span>

  <span class="token keyword">return</span> state<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>编辑 <code>src/App.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 1 导入 type 常量</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token constant">NUM_ADD</span><span class="token punctuation">,</span> <span class="token constant">NUM_SUBSTRA</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./store/actionType&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">mapDispatchToProps</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">dispatch</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">numAdd</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> action <span class="token operator">=</span> <span class="token punctuation">{</span>
        <span class="token comment">// 2  使用 type常量</span>
        type<span class="token operator">:</span> <span class="token constant">NUM_ADD</span><span class="token punctuation">,</span>
        value<span class="token operator">:</span> <span class="token number">1</span>
      <span class="token punctuation">}</span><span class="token punctuation">;</span>
      <span class="token function">dispatch</span><span class="token punctuation">(</span>action<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="使用action生成器来创建action"><a href="#使用action生成器来创建action" class="header-anchor">#</a> 使用action生成器来创建action</h4> <p>新建文件 <code>src/store/actionCreator/index.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span>  <span class="token constant">NUM_ADD</span><span class="token punctuation">,</span><span class="token constant">NUM_SUBSTRA</span><span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;../actionType&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">numAdd</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
  type<span class="token operator">:</span> <span class="token constant">NUM_ADD</span><span class="token punctuation">,</span>
  value<span class="token operator">:</span> <span class="token number">1</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">numSubstra</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
  type<span class="token operator">:</span> <span class="token constant">NUM_SUBSTRA</span><span class="token punctuation">,</span>
  value<span class="token operator">:</span> <span class="token number">1</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>修改 <code>App.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1 导入action</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> numAdd<span class="token punctuation">,</span> numSubstra <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./store/actionCreator&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">mapDispatchToProps</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">dispatch</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">numAdd</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// 2 修改为 生成器生成的action</span>
      <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token function">numAdd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="拆分和合并reducer"><a href="#拆分和合并reducer" class="header-anchor">#</a> 拆分和合并reducer</h4> <p>当需要共享的数据足够多时，一般会拆分多个reducer方便管理</p> <p>如 拆分成两个 <code>reducer</code> 一个是操作 nums的，一个是操作水果的。</p> <ol><li><p>编辑 <code>actionType/index.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token constant">NUM_ADD</span> <span class="token operator">=</span> <span class="token string">&quot;NUM_ADD&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token constant">NUM_SUBSTRA</span> <span class="token operator">=</span> <span class="token string">&quot;NUM_SUBSTRA&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 新增 增加 苹果action type</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token constant">APPLE_NUM_ADD</span> <span class="token operator">=</span> <span class="token string">&quot;APPLE_NUM_ADD&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 新增 减少 苹果action type</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token constant">APPLE_NUM_SUBSTRA</span> <span class="token operator">=</span> <span class="token string">&quot;APPLE_NUM_SUBSTRA&quot;</span><span class="token punctuation">;</span>
</code></pre></div></li> <li><p>编辑  <code>actionCreator/index.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 新增 添加苹果 action </span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">appleNumAdd</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
  type<span class="token operator">:</span> <span class="token constant">APPLE_NUM_ADD</span><span class="token punctuation">,</span>
  value<span class="token operator">:</span> <span class="token number">1</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">// 新增 减少苹果 action</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">appleNumSubstra</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
  type<span class="token operator">:</span> <span class="token constant">APPLE_NUM_SUBSTRA</span><span class="token punctuation">,</span>
  value<span class="token operator">:</span> <span class="token number">1</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div></li> <li><p>新建文件 <code>reducer/numReducer.js</code></p> <blockquote><p>将 以前 reducer/index.js  全部复制过去即可</p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token constant">NUM_ADD</span><span class="token punctuation">,</span> <span class="token constant">NUM_SUBSTRA</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;../actionType&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> defaultState <span class="token operator">=</span> <span class="token punctuation">{</span>
  payload<span class="token operator">:</span> <span class="token punctuation">{</span>
    num<span class="token operator">:</span> <span class="token operator">-</span><span class="token number">1</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> defaultState<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token constant">NUM_ADD</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> newState <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>
    newState<span class="token punctuation">.</span>payload<span class="token punctuation">.</span>num <span class="token operator">+=</span> action<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
    <span class="token keyword">return</span> newState<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token constant">NUM_SUBSTRA</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> newState <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>
    newState<span class="token punctuation">.</span>payload<span class="token punctuation">.</span>num <span class="token operator">-=</span> action<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
    <span class="token keyword">return</span> newState<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> state<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>新建文件 <code>reducer/fruitReducer.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token constant">APPLE_NUM_ADD</span><span class="token punctuation">,</span> <span class="token constant">APPLE_NUM_SUBSTRA</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;../actionType&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> defaultState <span class="token operator">=</span> <span class="token punctuation">{</span>
  payload<span class="token operator">:</span> <span class="token punctuation">{</span>
    appleNum<span class="token operator">:</span> <span class="token number">110</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> defaultState<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token constant">APPLE_NUM_ADD</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> newState <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>
    newState<span class="token punctuation">.</span>payload<span class="token punctuation">.</span>appleNum <span class="token operator">+=</span> action<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
    <span class="token keyword">return</span> newState<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token constant">APPLE_NUM_SUBSTRA</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> newState <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>
    newState<span class="token punctuation">.</span>payload<span class="token punctuation">.</span>appleNum <span class="token operator">-=</span> action<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
    <span class="token keyword">return</span> newState<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> state<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>编辑 <code>reducer/index.js</code> 用来合并 两个<code>reducer</code> <code>fruitReducer</code> 和 <code>numReducer</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1 引入 合并reducer的对象</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> combineReducers <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;redux&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> fruitReducer <span class="token keyword">from</span> <span class="token string">&quot;./fruitReducer&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> numReducer <span class="token keyword">from</span> <span class="token string">&quot;./numReducer&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 2 对象的形式传入 要合并的reducer</span>
<span class="token keyword">const</span> rootReducer <span class="token operator">=</span> <span class="token function">combineReducers</span><span class="token punctuation">(</span><span class="token punctuation">{</span> numReducer<span class="token punctuation">,</span> fruitReducer <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> rootReducer<span class="token punctuation">;</span>
</code></pre></div></li> <li><p>修改<code>App.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Component <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> connect <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;react-redux&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 1 多导入两个action appleNumAdd 和 appleNumSubstra</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> numAdd<span class="token punctuation">,</span> numSubstra<span class="token punctuation">,</span> appleNumAdd<span class="token punctuation">,</span> appleNumSubstra <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./store/actionCreator&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">AddNumBtn</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>numAdd<span class="token punctuation">}</span></span> <span class="token punctuation">&gt;</span></span><span class="token plain-text">+</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">SubstraNumBtn</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>numSubStra<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">-</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// 2 新增的组件</span>
<span class="token keyword">class</span> <span class="token class-name">AddFruitBtn</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 2.1 新绑定的事件</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>appleNumAdd<span class="token punctuation">}</span></span> <span class="token punctuation">&gt;</span></span><span class="token plain-text">+</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// 2 新增的组件</span>
<span class="token keyword">class</span> <span class="token class-name">SubstraFruitBtn</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 2.1 新绑定的事件</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>appleNumSubStra<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">-</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 3 修改过的页面代码</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      数量  </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>num<span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>hr</span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AddNumBtn</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">this</span><span class="token punctuation">.</span><span class="token attr-value">props</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AddNumBtn</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">SubstraNumBtn</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">this</span><span class="token punctuation">.</span><span class="token attr-value">props</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">SubstraNumBtn</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>hr</span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      水果数量  </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>appleNum<span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">/* 3.1 引入新组件 */</span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AddFruitBtn</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">this</span><span class="token punctuation">.</span><span class="token attr-value">props</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AddFruitBtn</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">/* 3.1 引入新组件 */</span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">SubstraFruitBtn</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">this</span><span class="token punctuation">.</span><span class="token attr-value">props</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">SubstraFruitBtn</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token function-variable function">mapStateToProps</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 4 修改数据的获取方法</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    num<span class="token operator">:</span> state<span class="token punctuation">.</span>numReducer<span class="token punctuation">.</span>payload<span class="token punctuation">.</span>num<span class="token punctuation">,</span>
    appleNum<span class="token operator">:</span> state<span class="token punctuation">.</span>fruitReducer<span class="token punctuation">.</span>payload<span class="token punctuation">.</span>appleNum
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token function-variable function">mapDispatchToProps</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">dispatch</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">numAdd</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token function">numAdd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token function-variable function">numSubStra</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token function">numSubstra</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token comment">// 5 新增的action</span>
    <span class="token function-variable function">appleNumAdd</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token function">appleNumAdd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token comment">// 5 新增的action</span>
    <span class="token function-variable function">appleNumSubStra</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token function">appleNumSubstra</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// 3 用 connect 将store中的数据通过props的方式传递到App上</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">connect</span><span class="token punctuation">(</span>mapStateToProps<span class="token punctuation">,</span> mapDispatchToProps<span class="token punctuation">)</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span>

</code></pre></div></li> <li><p>最终结果</p> <p><img src="/heima2020/assets/img/1560268076127.1a25f79f.png" alt="1560268076127"></p></li></ol> <h4 id="添加异步action-redux-thunk"><a href="#添加异步action-redux-thunk" class="header-anchor">#</a> 添加异步action redux-thunk</h4> <p>想象一下，我们对数据库进行查询，编辑和删除，其实都是异步操作。现在，让我们的应用支持异步<code>action</code>操作。</p> <ol><li><p>安装依赖 <code>redux-thunk</code></p> <div class="language-js extra-class"><pre class="language-js"><code>yarn add redux<span class="token operator">-</span>thunk <span class="token operator">--</span>dev
</code></pre></div></li> <li><p>修改<code>store/index.js</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 1 引入 redux的中间件连接器</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> createStore<span class="token punctuation">,</span> applyMiddleware <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;redux&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> reducer <span class="token keyword">from</span> <span class="token string">&quot;./reducer&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 1 引入 redux-thunk</span>
<span class="token keyword">import</span> reduxThunk <span class="token keyword">from</span> <span class="token string">&quot;redux-thunk&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 2 使用中间件连接器将redux-thunk传入 store构造器</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">createStore</span><span class="token punctuation">(</span>reducer<span class="token punctuation">,</span> <span class="token function">applyMiddleware</span><span class="token punctuation">(</span>reduxThunk<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div></li> <li><p>修改 <code>actionCreator/index.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1 修改 减少苹果的action 为异步的形式</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">appleNumSubstra</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
   <span class="token comment">// 2 返回一个函数</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token parameter">dispatch</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// 3 开启异步  后期将 setTimeout 替换成异步的方式即可</span>
    <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> action <span class="token operator">=</span> <span class="token punctuation">{</span>
        type<span class="token operator">:</span> <span class="token constant">APPLE_NUM_SUBSTRA</span><span class="token punctuation">,</span>
        value<span class="token operator">:</span> <span class="token number">1</span>
      <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token comment">// 4 开启派发</span>
      <span class="token function">dispatch</span><span class="token punctuation">(</span>action<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ol> <h3 id="小结"><a href="#小结" class="header-anchor">#</a> 小结</h3> <p>当对redux流程熟悉后，使用流程应该是这个样子的</p> <ol start="2"><li>编写action生成器</li> <li>编写reducer</li> <li>编写store</li> <li>连接store和组件</li> <li>。。。</li></ol> <h2 id="react-插件"><a href="#react-插件" class="header-anchor">#</a> react 插件</h2> <h3 id="vs-code插件"><a href="#vs-code插件" class="header-anchor">#</a> vs code插件</h3> <ol><li><p><code>Simple React Snippets</code>   react的快捷代码段</p> <p><img src="/heima2020/assets/img/1560268972967.3d6765d0.png" alt="1560268972967"></p></li></ol> <h3 id="chrome插件"><a href="#chrome插件" class="header-anchor">#</a> chrome插件</h3> <ol><li><p><code>React Developer Tools</code></p> <p><img src="" alt="1560269086393"></p></li> <li><p><code>Redux DevTools</code></p> <p><img src="" alt="1560269103715"></p></li></ol> <h4 id="redux-devtools"><a href="#redux-devtools" class="header-anchor">#</a> Redux DevTools</h4> <ol><li><p>没使用异步 <code>react-thunk</code>时，编辑文件   <code>store/index.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> createStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;redux&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> reducer <span class="token keyword">from</span> <span class="token string">&quot;./reducer&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">createStore</span><span class="token punctuation">(</span>reducer<span class="token punctuation">,</span>
  <span class="token comment">// 给谷歌调试工具使用的</span>
  window<span class="token punctuation">.</span>__REDUX_DEVTOOLS_EXTENSION__ <span class="token operator">&amp;&amp;</span> window<span class="token punctuation">.</span><span class="token function">__REDUX_DEVTOOLS_EXTENSION__</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div></li> <li><p>使用了异步 <code>react-thunk</code>时，编辑文件   <code>store/index.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> createStore<span class="token punctuation">,</span> applyMiddleware<span class="token punctuation">,</span>compose <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> reducer <span class="token keyword">from</span> <span class="token string">&quot;./reducer&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> thunk <span class="token keyword">from</span> <span class="token string">'redux-thunk'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> composeEnhancers <span class="token operator">=</span>
  <span class="token keyword">typeof</span> window <span class="token operator">===</span> <span class="token string">'object'</span> <span class="token operator">&amp;&amp;</span>
  window<span class="token punctuation">.</span>__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ <span class="token operator">?</span>   
    window<span class="token punctuation">.</span><span class="token function">__REDUX_DEVTOOLS_EXTENSION_COMPOSE__</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">:</span> compose<span class="token punctuation">;</span>

<span class="token keyword">const</span> enhancer <span class="token operator">=</span> <span class="token function">composeEnhancers</span><span class="token punctuation">(</span>
  <span class="token function">applyMiddleware</span><span class="token punctuation">(</span>thunk<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">createStore</span><span class="token punctuation">(</span>reducer<span class="token punctuation">,</span> enhancer<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span>  store<span class="token punctuation">;</span>
</code></pre></div></li></ol></div> <footer class="page-edit"><!----> <!----></footer> <!----> </main></div><div class="global-ui"><!----></div></div>
    <script src="/heima2020/assets/js/app.e2adc9d2.js" defer></script><script src="/heima2020/assets/js/2.7389c9d3.js" defer></script><script src="/heima2020/assets/js/13.7524b74f.js" defer></script>
  </body>
</html>
